<?php
/*
 * ----------------------------------------------------------------------------
 * Member Authentication (Twitter OAuth and Redux)
 * Uses Twitter OAuth API
 * Originates from the ReduxAuth library by Mathew Davies
 * ----------------------------------------------------------------------------
 */
class Welcome extends Controller {
	// holds stage
	var $oauth_state;
	// either request or authenticated key
	var $oauth_token;
	// stores request details
	var $oauth_request_token;
	var $oauth_request_token_secret;
	// stores authenticated deatils	
	var $oauth_access_token;
	var $oauth_access_token_secret;
	// for use with creating obj
	var $oauth_token_key;
	var $oauth_token_key_secret;
	// twitter authentication library objeect
	var $tAuth; 

	/*
	 * Switch based on where in the process you are
	 *
	 * 'default': Get a request token from twitter for new user
	 * 'returned': The user has authorize the app on twitter
	 * @author chardcastle
	 */
	function index()
	{
		$this->load->library('session');
		$this->load->helper('form');
		$this->load->helper('url');
		if($this->input->get('clear')){
			// restart process
			$this->session->sess_destroy();
			$this->oauth_token = 'start';
		}
		// Set state if previous session
		$this->oauth_state 					= $this->session->userdata('oauth_state');
		// Checks if oauth_token is set from returning from twitter
		$this->oauth_request_token 			= $this->session->userdata('oauth_request_token');
		$this->oauth_request_token_secret 	= $this->session->userdata('oauth_request_token_secret');	
		$this->oauth_access_token 			= $this->session->userdata('oauth_access_token');
		$this->oauth_access_token_secret 	= $this->session->userdata('oauth_access_token_secret');
		// Checks if oauth_token is set from returning from twitter - also works for $this->input->get('')
		// $_REQUEST['oauth_token']
		// Look up for an OAuth token in database against session id or look in the URL
		$this->oauth_token 					= $this->input->get('oauth_token');
		// local vars
		$loggedIn = false;
		$content = '';
		$localKeys = array();
		$requestUrl = NULL;

		// Check for state in session or url
		if($this->oauth_token && $this->oauth_state === 'start'){
			$this->oauth_state = 'returned';
			$this->session->set_userdata('oauth_state','returned');
		}		
		// Check for state in database 
		if($localKeys = $this->Auth_model->preEstablished()){
			$this->oauth_state = 'loadLocal';
			$this->oauth_token_key 			= $localKeys['oauth_token'];
			$this->oauth_token_key_secret 	= $localKeys['oauth_token_secret'];
		}
		if($this->oauth_state != 'loadLocal'){
			// no active session found in database, seek out or request
			switch ($this->oauth_state) {
			  default:
				// load blank auth object to begin request
				$this->loadTauth();
				// Request tokens from twitter
				$tok = $this->tAuth->getRequestToken();
				// Save tokens for later
				$token = $tok['oauth_token'];
				$this->session->set_userdata('oauth_request_token',$token);
				$this->session->set_userdata('oauth_request_token_secret',$tok['oauth_token_secret']);

				$this->session->set_userdata('oauth_state','start');
				$requestUrl = $this->tAuth->getAuthorizeURL($token);
				break;
			  case 'returned':		
					$this->loadFromTwitter();
				break;
			}
		}
		// if there's a library object with access, use it to get user data
		if($this->tAuth){
			$userData = 'https://twitter.com/account/verify_credentials.json';
			$userData = $this->tAuth->OAuthRequest($userData, array(), 'GET');
			$user = json_decode($userData,true);
			$loggedIn = true;
			// save user data if there is none already
			$this->Auth_model->saveUserData($userData,$userData["id"]);
		}
		$data = array(
			"title" => "Authenticate with OAuth",
			"user" => $user,
			"requestUrl" => $requestUrl,
			"oauth_token" => $this->oauth_token,
			"loggedIn" => $loggedIn
		);
		$this->load->view("welcome_message",$data);	
	}

	/*
	Twitter has returned to the designated URL with token in url
	 If the access tokens are already set skip to the API call
	*/
	private function loadFromTwitter(){		
		if (!$this->session->userdata('oauth_access_token') && 
			!$this->session->userdata('oauth_access_token_secret')) {
			// no authenticated token -> make exchange request token for authenticated token
			$this->oauth_token_key 			= $this->session->userdata('oauth_request_token');
			$this->oauth_token_key_secret 	= $this->session->userdata('oauth_request_token_secret');
			// load OAuth obj
			$this->loadTauth();
			// Request access tokens from twitter
			if($tok = $this->tAuth->getAccessToken()){
				if(isset($tok['oauth_token']) && isset($tok['oauth_token_secret'])){
					$this->oauth_token_key 			= $tok['oauth_token'];
					$this->oauth_token_key_secret 	= $tok['oauth_token_secret'];
					$this->session->set_userdata('oauth_access_token',$tok['oauth_token']);
					$this->session->set_userdata('oauth_access_token_secret',$tok['oauth_token_secret']);
					// make $this->tAuth the twitter oauth obj
					// needs development
					$this->saveAuthKeys($tok);
					$this->loadTauth();
				}else{
					// could not get access token no internetz / twitter is down
					$this->tAuth = false;
					log_message('error','could not get access token no internetz / twitter is down');
					return false;
				}
			}			
		}
		// new session as authenticated user
		$this->oauth_token_key 			= $this->session->userdata('oauth_access_token');
		$this->oauth_token_key_secret	= $this->session->userdata('oauth_access_token_secret');
		$this->loadTauth();
		return true;
		
	}
	public function loadTauth(){
		/* Create TwitterOAuth with app key/secret and user access key/secret */
		$oAuthParams = array(
				$this->config->item('twitter_consumer_key'),
				$this->config->item('twitter_consumer_secret'),
				$this->oauth_token_key,
				$this->oauth_token_key_secret);
		/* Run request on twitter API as user. */
		$this->load->library('twitteroauth',$oAuthParams,'tAuth');
	}
	/*
		Usage example http://twitter.com/statuses/followers/12345.json 
	*/ 	
	public function getFollowers(){
		if($username = $this->input->post("twitterUsername")){
			$this->load->library('curl');
			$this->load->helper('file');
			$tweets = $this->curl->simple_get('http://twitter.com/statuses/followers/'.$username .'.json');
			if(!write_file($this->config->item('user_tweets_dir'),$tweets)){
				log_message('error','file write fail');
			}

		}
	}
	private function saveAuthKeys($token){
		log_message('debug','controller: saveAuthKeys body');
		$data = array(
			'oauth_token' => $token['oauth_token'],
			'user_id' => $token['user_id'],
			'oauth_token_secret' => $token['oauth_token_secret'],
			'session_id' => $this->session->userdata('session_id'),
			'ip_address' => $this->input->ip_address(),
			'user_agent' => $this->input->user_agent(),
			'last_activity' => time(),
			'user_data' => json_encode($token)
		);		
		return($this->Auth_model->saveAuthToken($data));
	}
	/**
		Each of the following methods are written for the redux authentication library.
		By "Mathew"
	*/
	/**
	 * activate
	 * doesn't currently work
	 *
	 * @return void
	 * @author Mathew
	 **/
	function activate()
	{
	    $this->form_validation->set_rules('code', 'Verification Code', 'required');
	    $this->form_validation->set_error_delimiters('<p class="error">', '</p>');
	    
	    if ($this->form_validation->run() == false)
	    {
	        $data['content'] = $this->load->view('activate', null, true);
	        $this->load->view('template', $data);
	    }
	    else
	    {
	        $code = $this->input->post('code');
			$activate = $this->redux_auth->activate($code);
		    
			if ($activate)
			{
				$this->session->set_flashdata('message', '<p class="success">Your Account is now activated, please login.</p>');
	            redirect('welcome/activate');
			}
			else
			{
				$this->session->set_flashdata('message', '<p class="error">Your account is already activated or doesn\'t need activating.</p>');
	            redirect('welcome/activate');
			}
	    }
	}
	
	/**
	 * register
	 *
	 * @return void
	 * @author Mathew
	 **/
	function register()
	{
	    $this->form_validation->set_rules('username', 'Username', 'required|callback_username_check');
	    $this->form_validation->set_rules('email', 'Email Address', 'required|callback_email_check|valid_email');
	    $this->form_validation->set_rules('password', 'Password', 'required');
	    $this->form_validation->set_error_delimiters('<p class="error">', '</p>');
	    
	    if ($this->form_validation->run() == false)
	    {
	        $data['content'] = $this->load->view('register', null, true);
	        $this->load->view('template', $data);
	    }
	    else
	    {
	        $username = $this->input->post('username');
	        $email    = $this->input->post('email');
	        $password = $this->input->post('password');
	        
	        $register = $this->redux_auth->register($username, $password, $email);
	        
	        if ($register)
	        {
	            $this->session->set_flashdata('message', '<p class="success">You have now registered. Please login.</p>');
	            redirect('welcome/register');
	        }
	        else
	        {
	            $this->session->set_flashdata('message', '<p class="error">Something went wrong, please try again or contact the helpdesk.</p>');
	            redirect('welcome/register');
	        }
	    }
	}
	
	/**
	 * Username check
	 *
	 * @return void
	 * @author Mathew
	 **/
	public function username_check($username)
	{
	    $check = $this->redux_auth_model->username_check($username);
	    
	    if ($check)
	    {
	        $this->form_validation->set_message('username_check', 'The username "'.$username.'" already exists.');
	        return false;
	    }
	    else
	    {
	        return true;
	    }
	}
	
	/**
	 * Email check
	 *
	 * @return void
	 * @author Mathew
	 **/
	public function email_check($email)
	{
	    $check = $this->redux_auth_model->email_check($email);
	    
	    if ($check)
	    {
	        $this->form_validation->set_message('email_check', 'The email "'.$email.'" already exists.');
	        return false;
	    }
	    else
	    {
	        return true;
	    }
	}
	
	/**
	 * login
	 *
	 * @return void
	 * @author Mathew
	 **/
	function login()
	{
	    $this->form_validation->set_rules('email', 'Email Address', 'required');
	    $this->form_validation->set_rules('password', 'Password', 'required');
	    $this->form_validation->set_error_delimiters('<p class="error">', '</p>');
	    
	    if ($this->form_validation->run() == false)
	    {
	        $data['content'] = $this->load->view('login', null, true);
	        $this->load->view('template', $data);
	    }
	    else
	    {
	        $email    = $this->input->post('email');
	        $password = $this->input->post('password');
	        
	        $login = $this->redux_auth->login($email, $password);
		    
	        redirect('welcome/status');
	    }
	}
	
	/**
	 * logout
	 *
	 * @return void
	 * @author Mathew
	 **/
	function logout()
	{
		die("Log out by removing session");
		$this->session->remove("oauth_token");
		$this->redux_auth->logout();
		redirect('welcome/status');
	}
	
	/**
	 * status
	 *
	 * @return void
	 * @author Mathew
	 **/
	function status()
	{
	    $data['status'] = $this->Auth_model->logged_in();
	    $data['content'] = $this->load->view('authenticate/status', $data, true);
	    $this->load->view('welcome_message', $data);
	}
	/**
	 * change password
	 *
	 * @return void
	 * @author Mathew
	 **/
	function change_password()
	{	    
	    $this->form_validation->set_rules('old', 'Old password', 'required');
	    $this->form_validation->set_rules('new', 'New Password', 'required|matches[new_repeat]');
	    $this->form_validation->set_rules('new_repeat', 'Repeat New Password', 'required');
	    $this->form_validation->set_error_delimiters('<p class="error">', '</p>');
	    
	    if ($this->form_validation->run() == false)
	    {
	        $data['content'] = $this->load->view('change_password', null, true);
	        $this->load->view('template', $data);
	    }
	    else
	    {
	        $old = $this->input->post('old');
	        $new = $this->input->post('new');
	        
	        $identity = $this->session->userdata($this->config->item('identity'));
	        
	        $change = $this->redux_auth->change_password($identity, $old, $new);
		
    		if ($change)
    		{
    			$this->logout();
    		}
    		else
    		{
    			echo "Password Change Failed";
    		}
	    }
	}
	
	/**
	 * forgotten password
	 *
	 * @return void
	 * @author Mathew
	 **/
	function forgotten_password()
	{
	    $this->form_validation->set_rules('email', 'Email Address', 'required');
	    $this->form_validation->set_error_delimiters('<p class="error">', '</p>');
	    
	    if ($this->form_validation->run() == false)
	    {
	        $data['content'] = $this->load->view('forgotten_password', null, true);
	        $this->load->view('template', $data);
	    }
	    else
	    {
	        $email = $this->input->post('email');
			$forgotten = $this->redux_auth->forgotten_password($email);
		    
			if ($forgotten)
			{
				$this->session->set_flashdata('message', '<p class="success">An email has been sent, please check your inbox.</p>');
	            redirect('welcome/forgotten_password');
			}
			else
			{
				$this->session->set_flashdata('message', '<p class="error">The email failed to send, try again.</p>');
	            redirect('welcome/forgotten_password');
			}
	    }
	}
	
	/**
	 * forgotten_password_complete
	 *
	 * @return void
	 * @author Mathew
	 **/
	public function forgotten_password_complete()
	{
	    $this->form_validation->set_rules('code', 'Verification Code', 'required');
	    $this->form_validation->set_error_delimiters('<p class="error">', '</p>');
	    
	    if ($this->form_validation->run() == false)
	    {
	        redirect('welcome/forgotten_password');
	    }
	    else
	    {
	        $code = $this->input->post('code');
			$forgotten = $this->redux_auth->forgotten_password_complete($code);
		    
			if ($forgotten)
			{
				$this->session->set_flashdata('message', '<p class="success">An email has been sent, please check your inbox.</p>');
	            redirect('welcome/forgotten_password');
			}
			else
			{
				$this->session->set_flashdata('message', '<p class="error">The email failed to send, try again.</p>');
	            redirect('welcome/forgotten_password');
			}
	    }
	}
	
	/**
	 * Profile
	 *
	 * @return void
	 * @author Mathew
	 **/
	public function profile()
	{
	    if ($this->redux_auth->logged_in())
	    {
	        $data['profile'] = $this->redux_auth->profile();
	        $data['content'] = $this->load->view('profile', $data, true);
	        $this->load->view('template', $data);
	    }
	    else
	    {
	        redirect('welcome/login');
	    }
	}
}

/* End of file welcome.php */
/* Location: ./system/application/controllers/welcome.php */
